! MockLinker - version 1.8 of 5/9/86 ToolBox InitGraf(@_ThePort) ToolBox InitCursor ToolBox InitFonts ToolBox InitWindows ToolBox TEInit ToolBox InitDialogs(@@ResumeProc) ToolBox FlushEvents($FF77),NIL ! ToolBox OpenResFile("MockL.Rsrc"),NIL sfReply=New(74) textType='TEXT' inParam=New(80) inBuffer=New(522) outParam=New(80) outBuffer=New(522) eventRec=New(16) inWord=New(256) junkStr=New(256) rect=New(8) ! Set up the main output window ! ToolBox SetRect(rect,7,46,504,332) ToolBox GetNewWindow(128,NIL,-1),window ToolBox SetPort(window) ToolBox TextFont(4) ToolBox TextSize(9) ! Get the input file name GetInFile: goResEdit=0 ! usePutFile is actually picked up in the dlgHook ! Values are being put into them now just in case usePutFile=1 ToolBox SFGetFile(ASL(75,16)+75,"",@@GFFileFilter,1,@textType,@@GFDlgHook,sfReply) If Peek(sfReply)=0 Then End If goResEdit Then Do ToolBox GetString(256),resEditNameHandle: Gosub ResErr ToolBox HLock(resEditNameHandle): Gosub ChkErr ToolBox OpenResFile(LPeek(resEditNameHandle)),ret If ret=-1 Then Do ToolBox HUnlock(resEditNameHandle) Beep Goto GetInFile Doend LPoke rect,LPeek(resEditNameHandle) LPoke rect+4,0 ToolBox Launch(rect) Doend ! Set up the input & output file names fnameLen=Peek(sfReply+10) inName=New(fnameLen+1) outName=New(fnameLen+1) For i=0 To fnameLen Do Poke inName+i,Peek(sfReply+10+i) Poke outName+i,Peek(sfReply+10+i) Doend inVolume=WPeek(SFReply+6) outVolume=WPeek(SFReply+6) For i=0 To 3 Poke outName+fnameLen+i-3,Peek(".Obj"+i+1) If usePutFile Then Do ToolBox SFPutFile(ASL(100,16)+85,"Select the output file:",outName,NIL,sfReply) If Peek(sfReply)=0 Then GetInFile Free outName str1=sfReply+10 outName=New(Peek(str1)+1) str2=outName Gosub CopyStr outVolume=WPeek(SFReply+6) Doend ToolBox SetPort(window) Cls Print "Input file name: ";String(inName) Print "Output file name: ";String(outName) Print ! Open the input file paramBlock=inParam: Gosub ZeroParam LPoke inParam+18,inName WPoke inParam+22,inVolume LPoke inParam+28,inBuffer Poke inParam+27,1 ToolBox Open(inParam): Gosub ChkErr ! Open the output file paramBlock=outParam: Gosub ZeroParam LPoke outParam+18,outName WPoke outParam+22,outVolume ToolBox Create(outParam) If _OSErr=0 | _OSErr=-48 Then Do LPoke outParam+28,outBuffer Poke outParam+27,2 ToolBox OpenRF(outParam) If _OSErr=0 Then Do LPoke paramBlock+28,0 ToolBox SetEof(outParam) Doend Doend Gosub ChkErr symTab=NIL: symList=NIL: numSymbols=0: abort=0 pass=1: Print "Pass 1": Gosub DoPass: pass=2: Print "Pass 2" WPoke inParam+44,1 LPoke inParam+46,0 ToolBox SetFPos(inParam): Gosub ChkErr WPoke inParam+44,0 errorCount=0 globalMax=globalSize codeLen=PC+4 resLen=codeLen+32 ! Write the resource file header long=$00000100 : Gosub WriteLong long=$0100+resLen: Gosub WriteLong long= resLen: Gosub WriteLong long=$0000003E : Gosub WriteLong For i=1 To 240 Do byte=0: Gosub WriteByte DoEnd ! Write CODE resource #0 long=$00000018 : Gosub WriteLong long=$00000028 : Gosub WriteLong long=globalSize: Gosub WriteLong long=$00000008 : Gosub WriteLong long=$00000020 : Gosub WriteLong long=$00003F3C : Gosub WriteLong long=$0001A9F0 : Gosub WriteLong ! Write CODE resource #1 long=codeLen : Gosub WriteLong long=$00000001: Gosub WriteLong If abort=0 Then Gosub DoPass codeSize=PC ! Write resource map long=$00000100 : Gosub WriteLong long=$0100+resLen: Gosub WriteLong long= resLen: Gosub WriteLong long=$0000003E : Gosub WriteLong long=$00000000: Gosub WriteLong long=$00000000: Gosub WriteLong long=$001C003E: Gosub WriteLong word=$0000 : Gosub WriteWord long='CODE' : Gosub WriteLong long=$0001000A: Gosub WriteLong long=$0000FFFF: Gosub WriteLong ! CODE #0 long=$20000000: Gosub WriteLong long=$00000000: Gosub WriteLong long=$0001FFFF: Gosub WriteLong ! CODE #1 long=$2400001C: Gosub WriteLong long=$00000000: Gosub WriteLong ! Close the files ToolBox Close(inParam) ToolBox Close(outParam) ! Set the output file's type to APPL paramBlock=outParam: Gosub ZeroParam LPoke outParam+18,outName WPoke outParam+22,WPeek(SFReply+6) ToolBox GetFileInfo(outParam): Gosub ChkErr LPoke outParam+32,'APPL' ToolBox SetFileInfo(outParam): Gosub ChkErr ! Free up allocated memory While symList­NIL Do p=symList symList=LPeek(symList) Free p Doend Free inName Free outName ! Done!!! Beep: Beep: Beep Print Print "Link finished!" Print "Code size = ";codeSize Print "Global size = ";globalSize Print "Number of symbols = ";numSymbols Print "Total errors = ";errorCount Print "Press mouse button to continue..."; ToolBox FlushEvents($3F),NIL Until ret ToolBox GetNextEvent($0A,junkStr),ret Goto GetInFile DoPass: eof=0: PC=0: globalSize=0 Gosub ReadWord While Peek(inWord)­0 Do Gosub Pause ToolBox UprString(inWord+1,Peek(inWord)) Gosub DoCmd Gosub ReadWord DoEnd Return Pause: If Inkey='.' Then If (_MODIFIERS & $100)=$100 Then Do Print "*** Link aborted! ***": eof=1: abort=1 Doend ToolBox SystemTask If Button Then BtnWait Return DoCmd: cmd=Peek(inWord+1) strLen=Peek(inWord)-1 strPtr=inWord+2 If (cmd³'0' & cmd²'9') | (cmd³'A' & cmd²'F') Then DoHex If cmd=';' | cmd='*' Then DoComment If cmd='<' Then DoNear If cmd='>' Then DoFar If cmd='W' Then DoWord If cmd='L' Then DoLong If cmd='V' Then DoVar If cmd=':' Then DoLabelHere If cmd='$' Then DoSpecial BadWord: Error="Invalid word" Goto Error DoHex: If Peek(inWord) % 2=1 Then BadHex i=1 While i'F' | (ch>'9' & ch<'A') Then Do hex=-1 Return Doend hex=ch-'0' If ch>'9' Then hex=hex-7 Return BadHex: Error="Bad hex word" Goto Error DoComment: Gosub ReadCh While ch­13 & eof=0 Do Gosub ReadCh Doend Return DoNear: Gosub Eval byte=value-(PC+1): Gosub WriteByte If byte<-128 | byte>127 Then Do error="Short branch out of range" Gosub Error Doend Return DoFar: Gosub Eval word=value-PC: Gosub WriteWord If word<-32768 | word>32767 Then Do error="Long branch out of range" Gosub Error Doend Return DoWord: Gosub Eval word=value: Gosub WriteWord Return DoLong: Gosub Eval long=value: Gosub WriteLong Return DoVar: For i=2 To Peek(inWord) If Peek(inWord+i)=',' Then DoVarSize error="Variable size not specified" Goto Error DoVarSize: varlen=i-2 strLen=Peek(inWord)-i strPtr=inWord+i+1 Gosub MakeJunk ToolBox StringToNum(junkStr),value globalSize=globalSize+value value=-globalSize strLen=varlen strPtr=inWord+2 Gosub DefSym Return DoLabelHere: value=PC Gosub DefSym Return DoSpecial: If Peek(inWord)<2 Then BadWord cmd=Peek(inWord+2) If cmd='F' Then DoFlags If cmd='S' Then DoSymbols If cmd='D' Then DoDebug Goto BadWord DoFlags: DoSymbols: word=0: Goto WriteWord DoDebug: long=$4E714E75: Goto WriteLong DefSym: Gosub FindSym If pass=2 & p­NIL & WPeek(p+16)­0 & LPeek(p+12)­value Then Do error="Multiply defined symbol" Gosub Error Doend If p­NIL Then Do LPoke p+12,value WPoke p+16,1 Doend If p=NIL Then Do flags=1 Gosub AddSym DoEnd Return RefSym: Gosub FindSym If pass=2 & (p=NIL | WPeek(p+16)=0) Then Do error="Undefined symbol" Gosub Error Doend If p=NIL Then Do flags=0: value=0 Gosub AddSym Doend value=LPeek(p+12) Return ! FindSym tries to locate the symbol referenced by strPtr & strLen in the ! symbol table. On return, if the symbol was not found, P=NIL. If the ! symbol was found, P points to its entry in the symbol table. Q points ! to the parent node's pointer to be changed for a new entry. FindSym: If strLen=0 Then BadSym Gosub MakeJunk str1=junkStr q=NIL p=symTab While p­NIL Do str2=p+18 Gosub CmpStr If cmp=0 Then Return If cmp<0 Then q=p+4 Else q=p+8 p=LPeek(q) Doend Return ! If after calling FindSym, P=NIL, call this routine to add the symbol ! in junkStr to the symbol table. VALUE is the symbol value, and FLAGS ! is the symbol's flags. Returns address of new symbol table entry in P. ! Q is the parent node's pointer for the new node (or NIL if it will be ! the root). AddSym: p=New(Peek(junkStr)+19): Gosub ChkErr Gosub ChkErr LPoke p,symList: symList=p LPoke p+4,0: LPoke p+8,0 LPoke p+12,value: WPoke p+16,flags For i=0 To Peek(junkStr) Poke p+i+18,Peek(junkStr+i) If q Then LPoke q,p Else symTab=p numSymbols=numSymbols+1 Return CmpStr: cmp=Peek(str1): If Peek(str2)